# main.py
import json
import sys
import time
import traceback
from datetime import datetime, timedelta

from PyQt6 import QtCore, QtGui, QtWidgets
from UI.UI_MainWindow import Ui_MainWindow  # 假设这是你的主窗口 UI 文件
from UI.pwdgh_d import Ui_Dialog  # 假设这是你的对话框 UI 文件
from command_process import SerialCommunicator
from qss import *

com_manager = SerialCommunicator()
PORTS = SerialCommunicator.detect_serial_ports()
_TRANSLATE = QtCore.QCoreApplication.translate
CURRENT_DATA_PATH = 'tmp_data/current_data.json'

WEEKDAYS_DATA_FORMAT = {
    "checkBox_Sun": 0,
    "checkBox_Mon": 1,
    "checkBox_Tue": 2,
    "checkBox_Wed": 3,
    "checkBox_Thu": 4,
    "checkBox_Fri": 5,
    "checkBox_Sat": 6,
}

TEMP_DATA_FORMAT = {
    "doubleSpinBox_temperatureDifferenceWarningThreshold": 0,
    "doubleSpinBox_temperatureDifferenceAlarmThreshold": 1,
    "doubleSpinBox_temperatureWarningThreshold": 2,
    "doubleSpinBox_temperatureAlarmThreshold": 3,
}


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.week_value_changed = False
        self.temp_value_changed = False
        self.dialog = Ui_Dialog()
        self.setupUi(self)

        self.init_signals()
        self.current_data = {}
        self.temp_value_list = [0 for _ in range(4)]
        self.week_value = ['0' for _ in range(7)]
        self.RADIO_BUTTON_DICT = {
            "radioButton_dtuOn": self.radioButton_dtuOff,
        }

        # 创建一个定时器用于定期更新状态,并且自动保活
        self.status_update_timer = QtCore.QTimer(self)
        self.status_update_timer.timeout.connect(self.keep_live)
        # 设置更新间隔为 60000 毫秒
        refresh_interval_ms = 60000
        self.status_update_timer.setInterval(refresh_interval_ms)
        # 创建一个定时器用于定期采集数据
        self.data_update_timer = QtCore.QTimer(self)
        self.data_update_timer.timeout.connect(self.read_collection)
        # 设置更新间隔为 60000 毫秒
        data_update_interval_ms = int(self.spinBox.value()) * 1000
        self.data_update_timer.setInterval(data_update_interval_ms)

        self.init_settings()

    def init_signals(self):
        """初始化信号连接"""

        self.pushButton.clicked.connect(self.time_calibration)  # 校时按钮
        self.pushButton_2.clicked.connect(self.read_configuration)
        self.pushButton_3.clicked.connect(self.read_collection)
        self.pushButton_4.clicked.connect(self.save_configuration)
        self.pushButton_5.clicked.connect(self.restart_action)  # 重启按钮
        self.pushButton_6.clicked.connect(self.save_as_factory_settings)  # 保存为出厂设置按钮
        self.pushButton_7.clicked.connect(self.restore_factory_settings)  # 恢复出厂设置按钮
        self.pushButton_8.clicked.connect(self.software_upgrade)  # 软件升级按钮
        self.pushButton_9.clicked.connect(lambda: self.keep_live(True))  # 保活按钮
        self.pushButton_10.clicked.connect(self.go_to_sleep)  # 休眠按钮
        self.pushButton_11.clicked.connect(self.clean_logs)  # 清空日志
        self.comboBox.currentIndexChanged.connect(self.on_combo_box_changed)
        self.comboBox_6.currentIndexChanged.connect(self.on_combo_box6_changed)
        self.checkBox_2.stateChanged.connect(self.auto_update)
        self.checkBox_2.stateChanged.connect(self.auto_keep_live)
        self.spinBox.editingFinished.connect(self.on_interval_value_changed)

        self.groupBox_week_power_contrl.toggled.connect(self.toggle_group_boxes)
        self.groupBox_lowPower.toggled.connect(self.toggle_group_boxes)

    def init_settings(self):

        self.setFixedSize(1016, 692)
        self.set_ports_select()
        self.clear_status_bar()
        self.data_update_timer.start()
        self.set_max_time()
        if self.checkBox.isChecked():
            self.status_update_timer.start()

    def set_max_time(self):
        # 设置最大时间为 11 小时 46 分 39 秒
        max_time = QtCore.QTime(11, 46, 39)

        # 遍历 groupBox_lowPower 中的所有 QTimeEdit 控件并设置最大时间
        for widget in self.groupBox_lowPower.findChildren(QtWidgets.QTimeEdit):
            widget.setMaximumTime(max_time)

    def auto_update(self):
        """自动更新采集数据"""
        if self.checkBox_2.isChecked():
            self.data_update_timer.start()
            self.spinBox.setEnabled(True)
        else:
            self.data_update_timer.stop()
            self.spinBox.setEnabled(False)

    def toggle_group_boxes(self, checked):
        self.groupBox_week_power_contrl.setChecked(checked)
        self.groupBox_lowPower.setChecked(checked)

    def auto_keep_live(self):
        """自动更新采集数据"""
        if self.checkBox.isChecked():
            self.status_update_timer.start()
        else:
            self.status_update_timer.stop()

    def clean_logs(self):
        self.textBrowser.clear()

    def on_interval_value_changed(self, ):
        """
        当 spinBox 的值发生变化时，打印当前值。
        """
        value = self.spinBox.value()
        self.data_update_timer.setInterval(value * 1000)
        print(f"自动采集间隔修改为: {value}")

    def keep_live(self, is_manually=False):

        """保活按钮的槽函数"""
        keep_live_cmd = com_manager.modbus_command(0x06, 0x00, 0x15, 0xcc, 0x77)
        response = com_manager.send_command(keep_live_cmd)
        self.record_log(f"保活结果: {response}")
        if is_manually:
            QtWidgets.QMessageBox.information(self, '执行结果', response)
        if '写入成功' not in response:
            self.set_status_offline()
        else:
            self.set_status_online()

    def read_configuration(self):
        """显示对话框"""
        print("数据读取")
        self.set_status_loading()
        app.processEvents()
        if self.read_configuration_parameters():
            self.record_log("数据读取成功")
            self.set_status_online()
        self.clear_status_bar()

    def _populate_table_widget(self, dialog, data):

        self.dialog.tableWidget.setColumnCount(6)
        self.dialog.tableWidget.setRowCount(len(data))

        # 设置垂直表头
        for i in range(len(data)):
            item = QtWidgets.QTableWidgetItem(i + 1)
            self.dialog.tableWidget.setVerticalHeaderItem(i, item)

        # 设置水平表头
        horizontal_headers = ["序号", "配置类型", "寄存器地址", "参数名称", "当前值", "目标值"]
        for i, header in enumerate(horizontal_headers):
            item = QtWidgets.QTableWidgetItem(header)
            item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)  # 居中显示
            item.setFont(QtGui.QFont("Arial", 10, QtGui.QFont.Weight.Bold))  # 设置字体样式
            self.dialog.tableWidget.setHorizontalHeaderItem(i, item)
        # 填充表格数据
        for row_idx, row_data in enumerate(data):
            for col_idx, cell_data in enumerate(row_data):
                item = QtWidgets.QTableWidgetItem(cell_data)
                item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)  # 居中显示
                self.dialog.tableWidget.setItem(row_idx, col_idx, item)

                # 设置第一列的单元格为可选
                if col_idx == 0:
                    item.setFlags(item.flags() | QtCore.Qt.ItemFlag.ItemIsUserCheckable)
                    item.setCheckState(QtCore.Qt.CheckState.Checked)  # 默认选中
                # 设置第六列（索引为 5）的字体颜色为红色
                if col_idx == 5:
                    item.setForeground(QtGui.QBrush(QtGui.QColor("red")))

        # 设置第三列的列宽
        self.dialog.tableWidget.setColumnWidth(3, 180)
        self.dialog.tableWidget.setColumnWidth(4, 150)
        self.dialog.tableWidget.setColumnWidth(5, 150)

    def set_ports_select(self):
        """
        设置端口选择下拉框
        :return:
        """
        # 清空下拉框
        self.comboBox.clear()

        # 初始化 com_manager 的端口为 None
        com_manager.port = None

        # 遍历端口列表
        for port in PORTS:
            print(f'get ports: {port.description}')

            # 将所有端口描述添加到下拉框
            self.comboBox.addItem(port.description)
        current_items = [self.comboBox.itemText(i) for i in range(self.comboBox.count())]
        for index, item in enumerate(current_items):
            if 'USB Serial Port' in item:
                # 设置该选项为当前选项
                self.comboBox.setCurrentIndex(index)
                break
        # 更新其他参数
        com_manager.baudrate = self.comboBox_6.currentText()
        com_manager.slave_id = int(self.spinBox_7.text())

    def on_combo_box_changed(self, index):
        """
        下拉框选择端口
        :param index:
        :return:
        """
        try:
            com_item_text = self.comboBox.currentText()
            for port in SerialCommunicator.detect_serial_ports():
                if port.description == com_item_text:
                    com_manager.port = port.device
                    break
            self.record_log(f"当前端口已切换为: {com_manager.port}")
            print(f"Selected option: {com_item_text}")
        except Exception as e:
            print(f"Error: {e}", traceback.format_exc())

    def on_combo_box6_changed(self, index):
        """
        下拉框选择端口
        :param index:
        :return:
        """
        try:
            com_item_text = self.comboBox_6.currentText()
            com_manager.baudrate = com_item_text
            self.record_log(f"波特率已切换为: {com_manager.baudrate}")
            print(f"Selected option: {com_item_text}")
        except Exception as e:
            print(f"Error: {e}", traceback.format_exc())

    def restart_action(self):
        """重启按钮的槽函数"""
        reply = QtWidgets.QMessageBox.question(
            self,
            '确认重启',
            '您确定要重启吗？',
            QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
            QtWidgets.QMessageBox.StandardButton.No
        )

        if reply == QtWidgets.QMessageBox.StandardButton.Yes:
            print("执行重启操作")
            self.unlock_devices()
            reboot_cmd = com_manager.modbus_command(0x06, 0x00, 0x0B, 0xcc, 0x77)
            response = com_manager.send_command(reboot_cmd)
            self.set_status_offline()
            self.record_log(f"重启结果:{response}")
            if '写入成功' not in response:
                QtWidgets.QMessageBox.information(self, '执行结果', response)

            else:
                QtWidgets.QMessageBox.information(self, '执行结果', '重启执行成功')
        else:
            print("用户选择了取消")

    def software_upgrade(self):
        """软件升级按钮的槽函数"""
        reply = QtWidgets.QMessageBox.question(
            self,
            '确认升级',
            '您确定要升级软件吗？',
            QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
            QtWidgets.QMessageBox.StandardButton.No
        )

        if reply == QtWidgets.QMessageBox.StandardButton.Yes:
            print("执行软件升级操作")
            self.unlock_devices()
            upgrade_cmd = com_manager.modbus_command(0x06, 0x00, 0x0D, 0xcc, 0x77)
            response = com_manager.send_command(upgrade_cmd)
            self.record_log(f"升级结果:{response}")
            if '写入成功' not in response:
                self.set_status_offline()
                QtWidgets.QMessageBox.information(self, '执行结果', response)
            else:
                QtWidgets.QMessageBox.information(self, '执行结果', '保存为出厂设置执行成功，请重新读取数据')

        else:
            print("用户选择了取消")

    def save_as_factory_settings(self):
        """保存为出厂设置按钮的槽函数"""
        reply = QtWidgets.QMessageBox.question(
            self,
            '确认保存',
            '您确定要保存为出厂设置吗？',
            QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
            QtWidgets.QMessageBox.StandardButton.No
        )

        if reply == QtWidgets.QMessageBox.StandardButton.Yes:
            print("执行保存为出厂设置操作")
            self.unlock_devices()
            save_as_factory_cmd = com_manager.modbus_command(0x06, 0x00, 0x0C, 0xaa, 0x55)
            response = com_manager.send_command(save_as_factory_cmd)
            self.record_log(f"保存为出厂设置结果:{response}")
            if '写入成功' not in response:
                self.set_status_offline()
                QtWidgets.QMessageBox.information(self, '执行结果', response)
            else:
                QtWidgets.QMessageBox.information(self, '执行结果', '保存为出厂设置执行成功，请重新读取数据')
        else:
            print("用户选择了取消")

    def restore_factory_settings(self):
        """恢复出厂设置按钮的槽函数"""
        reply = QtWidgets.QMessageBox.question(
            self,
            '确认恢复',
            '您确定要恢复出厂设置吗？',
            QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
            QtWidgets.QMessageBox.StandardButton.No
        )

        if reply == QtWidgets.QMessageBox.StandardButton.Yes:
            print("执行恢复出厂设置操作")
            self.unlock_devices()
            restore_factory_cmd = com_manager.modbus_command(0x06, 0x00, 0x0C, 0xcc, 0x77)
            response = com_manager.send_command(restore_factory_cmd)
            self.record_log(f"恢复出厂设置结果:{response}")
            self.set_status_offline()
            if '写入成功' not in response:
                QtWidgets.QMessageBox.information(self, '执行结果', response)
            else:
                QtWidgets.QMessageBox.information(self, '执行结果', '恢复出厂设置执行成功，请重新读取数据')
        else:
            print("用户选择了取消")

    def record_log(self, message):
        try:
            now_time = datetime.now()
            str_time = now_time.strftime("%Y-%m-%d %H:%M:%S")
            current_text = self.textBrowser.toPlainText()
            new_text = current_text + f"\n{str_time} {message}"
            self.textBrowser.setText(new_text)
            # 移动光标到最下方
            cursor = self.textBrowser.textCursor()
            cursor.movePosition(QtGui.QTextCursor.MoveOperation.End)
            self.textBrowser.setTextCursor(cursor)

            # 滚动到最下方
            self.textBrowser.ensureCursorVisible()
            # 滚动到最下方
            self.textBrowser.ensureCursorVisible()
        except Exception as e:
            print(f"Error: {e}")
            traceback.print_exc()

    def time_calibration(self):
        """时间校准按钮的槽函数"""
        now = datetime.now()
        value = now.strftime('%Y/%m/%d %H:%M:%S')
        reply = QtWidgets.QMessageBox.question(
            self,
            '校时确认',
            f'您确定更新系统时间为当前时间({value})吗？',
            QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
            QtWidgets.QMessageBox.StandardButton.No
        )

        if reply == QtWidgets.QMessageBox.StandardButton.Yes:
            self.unlock_devices()
            row_data = ('1', '系统配置', '0009', '主机时间（校时）', '', value)
            response = com_manager.write_to_serial(row_data)
            self.record_log(f'校时结果：{response}')
            if '写入成功' not in response:
                QtWidgets.QMessageBox.information(self, '执行结果', response)
                self.set_status_offline()
            else:
                QtWidgets.QMessageBox.information(self, '执行结果', '校时成功')

        else:
            print("用户选择了取消")

    def go_to_sleep(self):
        """休眠按钮的槽函数"""
        reply = QtWidgets.QMessageBox.question(
            self,
            '确认休眠',
            '您确定要执行休眠操作吗？',
            QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
            QtWidgets.QMessageBox.StandardButton.No
        )

        if reply == QtWidgets.QMessageBox.StandardButton.Yes:
            print("开始休眠！")
            self.unlock_devices()
            sleep_cmd = com_manager.modbus_command(0x06, 0x00, 0x14, 0xcc, 0x77)
            response = com_manager.send_command(sleep_cmd)
            self.record_log(f"休眠结果:{response}")
            if '写入成功' not in response:
                QtWidgets.QMessageBox.information(self, '执行结果', response)
                self.set_status_offline()
            else:
                QtWidgets.QMessageBox.information(self, '执行结果', '休眠成功')
        else:
            print("用户选择了取消")

    def save_configuration(self):
        """保存配置按钮的槽函数"""

        try:
            changed_list = self.get_group_box_values()
            if not changed_list:
                QtWidgets.QMessageBox.information(self, '提示', '当前参数没有被修改，无需保存')
                return
            dialog = QtWidgets.QDialog()

            self.dialog.setupUi(dialog)
            dialog.setWindowTitle(
                _TRANSLATE("Dialog", f"当前{len(changed_list)}个参数发生变化，请确认需要修改保存的参数"))
            self._populate_table_widget(self.dialog, changed_list)
            # 连接信号和槽函数

            dialog.accepted.connect(self.on_accepted_config)
            dialog.exec()
        except Exception as e:
            self.record_log(f"数据保存失败: {e}")
            print(f"Error: {e}", traceback.format_exc())

    def unlock_devices(self):
        data_protection_on = ('0', '系统配置', '00FF', '数据保护', 'False', 'True')
        com_manager.write_to_serial(data_protection_on)

    def on_accepted_config(self):
        print("模拟保存配置操作")
        try:
            # 保存当前数据到current_data.json
            self.write_to_json(CURRENT_DATA_PATH, self.current_data)
            # 获取对话框中的 tableWidget

            selected_rows_data = self.get_selected_rows_data()
            self.unlock_devices()
            # 创建进度条对话框
            progress_dialog = QtWidgets.QProgressDialog("Saving Rows", "Cancel", 0, len(selected_rows_data), self)
            progress_dialog.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
            progress_dialog.setWindowTitle("Progress")
            progress_dialog.setValue(0)  # 初始化进度条值
            progress_dialog.show()

            failed_rows = []  # 用于存储保存失败的行

            def update_progress(i):
                if i < len(selected_rows_data):
                    row_data = selected_rows_data[i]
                    res = com_manager.write_to_serial(row_data)
                    # print(res)
                    print(type(res))
                    if '写入成功' in res:
                        self.record_log(f"{row_data}写入成功")
                        progress_dialog.setValue(i + 1)
                        progress_dialog.setLabelText(f"Saving Row {i + 1} of {len(selected_rows_data)}")
                        QtCore.QTimer.singleShot(1000, lambda: update_progress(i + 1))  # 模拟延迟1秒
                    else:
                        failed_rows.append(row_data)  # 保存失败的行
                        progress_dialog.setValue(i + 1)
                        progress_dialog.setLabelText(f"Saving Row {i + 1} of {len(selected_rows_data)}")
                        QtCore.QTimer.singleShot(1000, lambda: update_progress(i + 1))  # 模拟延迟1秒
                else:
                    progress_dialog.setValue(len(selected_rows_data))
                    progress_dialog.close()  # 关闭进度条对话框
                    if failed_rows:
                        str_failed_rows = "\n".join([str(row) for row in failed_rows])
                        self.record_log(f"以下数据保存失败:\n{str_failed_rows}")
                        QtWidgets.QMessageBox.warning(self, "以下数据保存失败", f"失败清单:\n{str_failed_rows}")

                    else:
                        self.record_log("所有数据均已保存")
                        QtWidgets.QMessageBox.information(self, "完成", "所有数据均已保存")

            update_progress(0)
        except Exception as e:
            print(f"Error: {e}", traceback.format_exc())

    def refresh_configuration(self):
        """刷新配置按钮的槽函数"""
        self.get_group_box_values(is_update=False)
        print("模拟刷新配置操作")

    def get_selected_rows_data(self, ):
        table_widget = self.dialog.tableWidget

        # 获取第一列被选中的行
        selected_rows_data = []
        for row in range(table_widget.rowCount()):
            item = table_widget.item(row, 0)
            address = table_widget.item(row, 2).text()
            print(f'address:{address}')
            if address in ['0016', '0017', '0018', '0019', '001F']:
                continue
            if item is not None and item.checkState() == QtCore.Qt.CheckState.Checked:
                row_data = []
                for column in range(table_widget.columnCount()):
                    cell_item = table_widget.item(row, column)
                    row_data.append(cell_item.text() if cell_item else "")
                selected_rows_data.append(row_data)
        if self.week_value_changed:
            selected_rows_data.append(('99', '上电控制', '001F', '星期', '0', ''.join(self.week_value)[::-1]))
        if self.temp_value_changed:
            selected_rows_data.append(('999', '温度配置', '0016', '温度', '0', self.temp_value_list))
        return selected_rows_data

    def read_collection(self):
        """刷新数据按钮的槽函数"""
        self.set_status_loading()
        app.processEvents()
        print("读取采集数据")
        response = None
        try:
            children = self.groupBox_4.findChildren((QtWidgets.QLineEdit, QtWidgets.QComboBox))
            com_manager.slave_id = int(self.spinBox_7.text())
            command = com_manager.modbus_command(0x03, 0x01, 0x04,
                                                 0x00, 0x10)
            response = com_manager.send_command(command)

            with open(CURRENT_DATA_PATH, mode='r', encoding='utf-8') as json_file:
                current_data = json.load(json_file)
            for child in children:
                self.view_configuration_parameters(child, current_data, response)
        except Exception as e:
            print(f"Error: {e}", traceback.format_exc())
        json_string = json.dumps(response, indent=4, ensure_ascii=False)
        self.record_log(f'数据采集结果：{json_string}')
        self.clear_status_bar()
        if isinstance(response, dict):
            self.set_status_online()
        else:
            self.set_status_offline()

    def get_checked_controls(self):
        # 获取 groupBox 中的所有子控件
        group_boxes = [
            (self.groupBox_sys, 'sys_children'),
            (self.groupBox_lowPower, 'low_power_children'),
            (self.groupBox_temp, 'temp_children'),
            (self.groupBox_amp, 'amp_children'),
            (self.groupBox_week_power_contrl, 'groupBox_week_power_contrl'),
        ]

        checked_children = []

        for group_box, _ in group_boxes:
            if group_box.isChecked():
                checked_children.extend(group_box.findChildren(QtWidgets.QWidget))
        return checked_children

    def read_configuration_parameters(self):
        checked_children = self.get_checked_controls()
        com_manager.slave_id = int(self.spinBox_7.text())
        command = com_manager.modbus_command(0x03, 0x00, 0x00,
                                             0x00, 0x58)
        response = com_manager.send_command(command)

        if isinstance(response, dict) and len(response) >= 80:
            data_protection_command = com_manager.modbus_command(0x03, 0x00, 0xFF,
                                                                 0x00, 0x01)
            data_protection_response = com_manager.send_command(data_protection_command)
            response.update(data_protection_response)
        else:
            QtWidgets.QMessageBox.warning(self, '警告', f'数据获取失败:\n{response}')
            self.record_log(f'数据获取失败:\n{response}')
            self.set_status_offline()
            return False

        try:
            with open(CURRENT_DATA_PATH, mode='r', encoding='utf-8') as json_file:
                self.current_data = json.load(json_file)
            for child in checked_children:
                self.view_configuration_parameters(child, self.current_data, response)
            self.write_to_json(CURRENT_DATA_PATH, self.current_data)
        except Exception as e:
            print(f"Error: {e}", traceback.format_exc())
            QtWidgets.QMessageBox.warning(self, '警告', f'数据获取失败:\n{e}')
            self.record_log(f'数据获取失败:\n{e}')
            self.set_status_offline()
            return False
        return True

    def view_configuration_parameters(self, widget, current_data, response):
        object_name = widget.objectName()
        if not isinstance(response, dict):
            return
        if object_name in current_data:
            address = current_data.get(object_name)[1]
            value = str(response.get(address, '0'))
            if isinstance(widget, QtWidgets.QLineEdit):
                widget.setText(value)
            elif isinstance(widget, QtWidgets.QComboBox):
                widget.setCurrentText(value)
                if value in ['报警', '浸水', '低压']:
                    widget.setStyleSheet(ALARM_COMBOBOX)
                elif value == '预警':
                    widget.setStyleSheet(WARNING_COMBOBOX)
                else:
                    if widget.parentWidget() == self.groupBox_4 or object_name == 'comboBox_batteryStatus':
                        widget.setStyleSheet(NORMAL_COMBOBOX)
            elif isinstance(widget, QtWidgets.QDoubleSpinBox):
                widget.setValue(float(value))
            elif isinstance(widget, QtWidgets.QSpinBox):
                widget.setValue(int(value))
            elif isinstance(widget, QtWidgets.QTimeEdit):
                value = self.seconds_to_hhmmss(value)
                widget.setTime(QtCore.QTime.fromString(value, 'hh:mm:ss'))
            elif isinstance(widget, QtWidgets.QCheckBox):
                if object_name in WEEKDAYS_DATA_FORMAT.keys():
                    data_index = WEEKDAYS_DATA_FORMAT.get(object_name)
                    bool_value = True if value[data_index] in ['True', '1', 1] else False
                    widget.setChecked(bool_value)
                    value = str(int(bool_value))
                    # print(f'object_name:{object_name}, value:{value}')
            elif isinstance(widget, QtWidgets.QRadioButton):

                value = True if value in ['True', '1', 1] else False
                if not value:
                    widget = self.RADIO_BUTTON_DICT.get(object_name)
                widget.setChecked(True)
                value = str(value)
            elif isinstance(widget, QtWidgets.QDateTimeEdit):
                start_date = datetime(2001, 1, 1, 0, 0, 0)
                if not value or value == 'None':
                    value = '0'
                now = start_date + timedelta(seconds=int(value))
                widget.setDateTime(now)
                value = now.strftime('%Y/%m/%d %H:%M:%S')

            elif isinstance(widget, QtWidgets.QFrame):
                # 递归处理子控件
                children = widget.findChildren((QtWidgets.QFrame,))
                for child in children:
                    self.view_configuration_parameters(child, current_data, response, )
                return
            else:
                return

            current_data[object_name][-1] = value

    @staticmethod
    def seconds_to_hhmmss(seconds):
        hours = int(seconds) // 3600
        minutes = (int(seconds) % 3600) // 60
        seconds = int(seconds) % 60
        return f"{hours:02d}:{minutes:02d}:{seconds:02d}"

    def get_group_box_values(self, is_update=True):
        checked_children = self.get_checked_controls()
        changed = []
        try:
            # 打开并读取 JSON 文件
            with open(CURRENT_DATA_PATH, mode='r', encoding='utf-8') as json_file:
                self.current_data = json.load(json_file)
            for child in checked_children:
                self._collect_values(child, self.current_data, changed, is_update)
            if not is_update:
                self.write_to_json(CURRENT_DATA_PATH, self.current_data)
        except FileNotFoundError:
            print("File 'current_data.json' not found.")
        except json.JSONDecodeError:
            print("Error decoding JSON file.")
        except Exception as e:
            print(f"Error: {e}")
            traceback.print_exc()

        print(changed)
        return changed

    def write_to_json(self, json_path, data):
        try:
            with open(json_path, mode='w', encoding='utf-8') as json_file:
                json.dump(data, json_file, ensure_ascii=False, indent=4)
        except Exception as e:
            print(f"Error: {e}", traceback.format_exc())

    def _collect_values(self, widget, current_data, changed, is_update=True):
        # week_value = ['' for _ in range(7)]
        object_name = widget.objectName()
        if isinstance(widget, QtWidgets.QLineEdit):
            value = widget.text()
        elif isinstance(widget, QtWidgets.QComboBox):
            value = widget.currentText()
        elif isinstance(widget, QtWidgets.QSpinBox):
            value = widget.value()
        elif isinstance(widget, QtWidgets.QDoubleSpinBox):
            value = widget.value()
            if object_name in TEMP_DATA_FORMAT.keys():
                self.temp_value_list[TEMP_DATA_FORMAT.get(object_name)] = int(value * 10)
        elif isinstance(widget, QtWidgets.QRadioButton):
            value = widget.isChecked()
        elif isinstance(widget, QtWidgets.QDateTimeEdit):
            value = widget.text()
        elif isinstance(widget, QtWidgets.QTimeEdit):
            value = widget.text()
        elif isinstance(widget, QtWidgets.QCheckBox):
            value = str(int(widget.isChecked()))
            if object_name in WEEKDAYS_DATA_FORMAT.keys():
                self.week_value[WEEKDAYS_DATA_FORMAT.get(object_name)] = value
        elif isinstance(widget, QtWidgets.QFrame):
            # 递归处理子控件
            children = widget.findChildren((QtWidgets.QFrame,))
            for child in children:
                self._collect_values(child, current_data, changed, is_update)
            return
        else:
            return

        if object_name not in current_data:
            # print(f"{object_name} not in data")
            pass
        elif current_data[object_name][-1] != str(value):
            if object_name in WEEKDAYS_DATA_FORMAT.keys():
                self.week_value_changed = True
            if object_name in TEMP_DATA_FORMAT.keys():
                self.temp_value_changed = True
            if is_update:
                changed_data = (str(len(changed) + 1),) + tuple(
                    current_data[object_name][:-2] + current_data[object_name][-1:]) + (
                                   str(value),)
                changed.append(changed_data)
            current_data[object_name][-1] = str(value)

    def clear_status_bar(self):
        self.statusbar.showMessage("欢迎使用设备配置工具V2.0，使用中遇到问题请钉钉联系：赵启东")

    def set_status_online(self):
        self.toolButton.setStyleSheet(ONLINE_RADIO_BUTTON)
        self.toolButton.setText(_TRANSLATE("MainWindow", "在线"))

    def set_status_loading(self):
        self.statusbar.showMessage('数据读取中...........')
        self.toolButton.setStyleSheet(LOADING_RADIO_BUTTON)
        self.toolButton.setText(_TRANSLATE("MainWindow", "加载中"))

    def set_status_offline(self):
        self.toolButton.setStyleSheet(OFFLINE_RADIO_BUTTON)
        self.toolButton.setText(_TRANSLATE("MainWindow", "离线"))

    def set_cache_max(self, max_size):
        self.spinBox_cacheDateCounts.setMaximum(max_size)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
